package com.ideaaedi.springcloud.jd.user.config.ext;

import com.google.common.collect.Sets;
import com.ideaaedi.springcloud.jd.commonds.constant.BaseConstant;
import com.ideaaedi.springcloud.jd.commonds.enums.oauth2.ScopeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * (non-javadoc)
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.1.A
 */
@Slf4j
@Component
@RefreshScope
@SuppressWarnings({"deprecation", "AlibabaServiceOrDaoClassShouldEndWithImpl"})
public class ConfigMemoryClientDetailProvider implements ClientDetailsService {
    
    /** access_token有效时长(默认一天) */
    @Value("${oauth2.access-token-validity-seconds:86400}")
    private int oauth2AccessTokenValiditySeconds;
    
    /** refresh_token有效时长(默认30天) */
    @Value("${oauth2.refresher-token-validity-seconds:2592000}")
    private int oauth2RefreshTokenValiditySeconds;
    
    @Resource
    PasswordEncoder passwordEncoder;
    
    /**
     * 客户端缓存 (key - 客户端id, value - 客户端具体配置)
     */
    private final Map<String, ClientDetails> clientDetailsStore = new ConcurrentHashMap<>();
    
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        ClientDetails details = clientDetailsStore.get(clientId);
        if (details == null) {
            throw new NoSuchClientException("No client with requested id: " + clientId);
        }
        return details;
    }
    
    @PostConstruct
    public void init() {
        // 系统自身会用到的客户端
        BaseClientDetails systemUserClientDetails = new BaseClientDetails();
        systemUserClientDetails.setClientId(BaseConstant.SYSTEM_USER_CLIENT_ID);
        systemUserClientDetails.setClientSecret(passwordEncoder.encode(BaseConstant.SYSTEM_USER_CLIENT_SECRET));
        systemUserClientDetails.setScope(Collections.singletonList(ScopeEnum.SYSTEM_ALL.getScope()));
        systemUserClientDetails.setResourceIds(Sets.newHashSet(BaseConstant.SYSTEM_INNER_RESOURCE_ID));
        systemUserClientDetails.setAuthorizedGrantTypes(Arrays.asList(BaseConstant.SYSTEM_USER_AUTHORIZED_GRANT_TYPES));
        systemUserClientDetails.setAccessTokenValiditySeconds(oauth2AccessTokenValiditySeconds);
        systemUserClientDetails.setRefreshTokenValiditySeconds(oauth2RefreshTokenValiditySeconds);
        clientDetailsStore.put(BaseConstant.SYSTEM_USER_CLIENT_ID, systemUserClientDetails);
    }
}
